package com.LachesismStorm.lachesism.core.filter;

import com.LachesismStorm.lachesism.core.util.JwtTokenUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.web.authentication.WebAuthenticationDetailsSource;
import org.springframework.web.filter.OncePerRequestFilter;

import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

/**
 * 功能描述
 *
 * @author: Lachesism
 * @date: 2023年5月23日
 */
public class JwtAuthenticationTokenFilter extends OncePerRequestFilter {
    private static final Logger LOGGER = LoggerFactory.getLogger(JwtAuthenticationTokenFilter.class);
    @Autowired
    private UserDetailsService userDetailsService;
    @Autowired
    private JwtTokenUtil jwtTokenUtil;
    @Value("${jwt.tokenHeader}")
    private String tokenHeader;
    @Value("${jwt.tokenHead}")
    private String tokenHead;

    @Override
    protected void doFilterInternal(HttpServletRequest request,
                                    HttpServletResponse response,
                                    FilterChain chain) throws ServletException, IOException {
//        LachesismTools.behaviorWriterC(request);
//        这是过滤器的方法签名。它接受一个HttpServletRequest对象、一个HttpServletResponse对象和一个FilterChain对象，并抛出ServletException和IOException。
        String authHeader = request.getHeader(this.tokenHeader);
//        这一行使用tokenHeader变量从HTTP请求中检索授权头。
        if (authHeader != null && authHeader.startsWith(this.tokenHead)) {
//            这一行检查授权头是否不为null并以tokenHead变量的值开头。
            String authToken = authHeader.substring(this.tokenHead.length());// The part after "Bearer "
//            这一行通过删除标头前缀定义为tokenHead来提取授权头中的令牌部分
            String username = jwtTokenUtil.getUserNameFromToken(authToken);
//            这一行使用jwtTokenUtil实用程序类从授权头中提取的JWT令牌中检索用户名。
//            LOGGER.info("checking username:{}", username);
//            这一行记录正在验证的用户名。
            if (username != null && SecurityContextHolder.getContext().getAuthentication() == null) {
//                这一行检查用户名不为null并且不存在正在进行的身份验证上下文。
                UserDetails userDetails = this.userDetailsService.loadUserByUsername(username);
//                这一行使用userDetailsService从用户名中加载用户详细信息.
                if (jwtTokenUtil.validateToken(authToken, userDetails)) {
//                    这一行使用jwtTokenUtil实用程序类对给定用户详细信息验证JWT令牌.
                    UsernamePasswordAuthenticationToken authentication = new UsernamePasswordAuthenticationToken(userDetails, null, userDetails.getAuthorities());
//                    这一行使用先前检索的用户详细信息和权限创建一个UsernamePasswordAuthenticationToken实例.
                    authentication.setDetails(new WebAuthenticationDetailsSource().buildDetails(request));
//                    这一行使用WebAuthenticationDetailsSource类设置身份验证的详细信息.
                    LOGGER.info("登陆用户：{}，请求路径：{}", username, request.getRequestURL().toString());
//                    这一行记录用户成功认证的信息.
                    SecurityContextHolder.getContext().setAuthentication(authentication);
//                    这一行为当前请求设置身份验证上下文.
                }
            }
        }
        chain.doFilter(request, response);
    }
}
